package tp.model;

import java.util.*;
import tp.controller.Controlador;
import tp.view.BolaView;
import tp.view.CopyOfBoardView1;

/*La Clase de la Bola, que se mueve por todo el tablero*/
/**
 * @author Dr Von Nostrum v1.3 nuevos cambios, bola + inteligente v1.4 se ha
 *         hecho y terminado como se contactan dos objetos
 */
public class BolaDeFuego extends Bola {

	/**
	 * tiene posicion del tipo posicion
	 */
	public Posicion MiPosicion;

	String Clase = "BolaDeFuego";

	/**
	 * tiene posicionvieja del tipo posicion, que sirve para saber donde estaba
	 * antes de moverse
	 */
	public Posicion MiPosicionVieja = new Posicion(0, 0);

	/**
	 * la direccion esta dada por el vector (0.0;0.0) y miDireccion
	 */
	public Posicion MiDireccion;

	/**
	 * la cantidad de posiciones que se mueve sobre la traza del vector
	 * direccion y su posicion
	 */
	public int MiVelocidad = 10;

	public BolaView miVista;

	/**
	 * es una referencia a la lista de chocables
	 */
	private ColChocables ListaChocables;

	// private double MiRadio = 12;

	private boolean vivo = true;

	public BolaDeFuego() {
		this.MiPosicion = new Posicion(250, 90);
		this.MiDireccion = new Posicion(1, 1);
		this.MiDireccion.torcer();
		// Controlador.controlador.addChocable(this);
		// miVista = new BolaView(this);
		// CopyOfBoardView1.addVisible(new BolaView(this));
		// BoardView1.addVisible(new BolaView(this));
		miVista = new BolaView(this);
	}

	/**
	 * para calcular la direccion en la cual esta la bola yendo
	 * 
	 * @param X
	 * @param Y
	 */
	public void setMiDireccion(double X, double Y) {
		Posicion pos = new Posicion(X, Y);
		this.MiDireccion = pos.normalizar();
		;
	};

	public void setVelocidad(int Veloci) {
		this.MiVelocidad = Veloci;
	};

	public int getVelocidad() {
		return this.MiVelocidad;
	};

	public void setMiPosicion(Posicion Pos) {
		this.MiPosicion = Pos;
	};

	/**
	 * Devuelve la referencia a la posicion que se mueve que es la posicion a la
	 * cual se mueve
	 */
	public Posicion meMuevoA() {
		this.setMiPosicionVieja(this.MiPosicion);
		this.setMiPosicion(this.getMiPosicion().sumarPosicion(
				(this.MiDireccion.multiplicarPosicion(this.MiVelocidad))));
		return this.getMiPosicion();
	}

	/**
	 * Aca en hago, el objeto bola se mueve, y luego se fija si intercepto a
	 * algun otro objeto, en ese caso reacciona cambiando la direccion
	 * 
	 * @return una posicion que es la nueva
	 */
	public Posicion hago() {
		boolean choque = false;
		this.meMuevoA(); // aqui debajo se fija si choco
		Iterator it = Controlador.controlador.ListaChocables.iterator();
		while ((it.hasNext()) && (!choque)) {
			Chocable elemChoc = (Chocable) it.next();
			if ((elemChoc.meToca(this)) && (this != elemChoc)) {
				if ((elemChoc.getClase() != "Ladrillo")) {
					this.setMiPosicion(elemChoc.dondeMeToca(this));
					this.MiDireccion = MiDireccion.reflejar((elemChoc
							.miNormal(this)));
					this.setMiPosicion(this.getMiPosicion().sumarPosicion(
							(this.MiDireccion.multiplicarPosicion(0.1))));
					// MiDireccion.torcer();
				}
				elemChoc.meChocaron(this);
				choque = true;
			}
		}
		setChanged();// estas dos lineas le avisan a board view que se cambio
						// y que dibuje todo de nuevo
		notifyObservers();
		// me parece que ya esta arreglado... hay que probarlo
		return getMiPosicion();
		// .sumarPosicion(this.getMiDireccion().invertir().multiplicarPosicion(this.getMiRadio()))
	}

	/**
	 * @param listChocables
	 *            the listChocables to set
	 */
	public void setListaChocables(ColChocables listChocables) {
		ListaChocables = listChocables;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tp.Chocable#dondeMeToca(tp.Chocable) v 1.2 le puse invertir ver si
	 *      anda
	 */
	public Posicion dondeMeToca(Chocable elem) {
		while (this.getMiPosicion().distanciaA(elem.getMiPosicion()) < (this
				.getMiRadio() * 2)) {
			Posicion diferencia = elem.getMiPosicion().invertir();
			diferencia = diferencia.sumarPosicion(this.getMiPosicion());
			diferencia = diferencia.normalizar();
			diferencia = diferencia.multiplicarPosicion(0.01);
			this.setMiPosicion(this.getMiPosicion().sumarPosicion(diferencia));
		}
		Posicion posi = this.getMiPosicion().invertir();
		posi = posi.sumarPosicion(elem.getMiPosicion());
		posi = posi.normalizar();
		posi = posi.multiplicarPosicion(this.getMiRadio());
		posi = posi.sumarPosicion(this.getMiPosicion());
		return posi;
	}

	/**
	 * En este caso la bola cambia de direccion deacuerdo a donde la chocaron
	 * 
	 * @param recibe
	 *            el obj que lo choco
	 */
	public void meChocaron(Chocable elem) {
		while (this.getMiPosicion().distanciaA(elem.getMiPosicion()) < (this
				.getMiRadio())) {
			this.setMiPosicion(this.getMiPosicion().invertir().sumarPosicion(
					elem.getMiPosicion()).normalizar()
					.multiplicarPosicion(0.01));
		}
		this.MiDireccion = this.MiDireccion.reflejar(elem.miNormal(this));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tp.Chocable#meToca(tp.Chocable)
	 */
	public boolean meToca(Chocable elem) {
		double dist = this.getMiPosicion().distanciaA(elem.getMiPosicion());
		if (dist <= (this.getMiRadio() * 2)) {
			return true;
		}
		return false;
	}

	/**
	 * @return the miPosicion
	 */
	public Posicion getMiPosicion() {
		return MiPosicion;
	}

	/**
	 * @return the miPosicionVieja
	 */
	public Posicion getMiPosicionVieja() {
		return MiPosicionVieja;
	}

	/**
	 * @param miPosicionVieja
	 *            the miPosicionVieja to set
	 */
	public void setMiPosicionVieja(Posicion miPosicionVieja) {
		this.MiPosicionVieja = miPosicionVieja;
	};

	/**
	 * devuelve la normale que pueden interesar
	 * 
	 * @param recibe
	 *            de donde se le produce el choque (posicion y direccion)
	 * @return devuelve la normal que puede interesar
	 */
	public Posicion miNormal(Chocable elem) {
		Posicion Normal = (elem.getMiPosicion().invertir().sumarPosicion(this
				.dondeMeToca(elem)));
		if (this.getMiPosicion().sumarPosicion(Normal).equals(
				this.dondeMeToca(elem))) {
			return Normal;
		}
		return Normal.invertir();
	}

	/**
	 * devuelve la direccion de la bola
	 * 
	 * @param devuelve
	 *            la direccion
	 */
	public Posicion getMiDireccion() {
		return this.MiDireccion;
	}

	/**
	 * @return the miRadio
	 */
	public double getMiRadio() {
		return MiRadio;
	}

	/**
	 * @param miRadio
	 *            the miRadio to set
	 */
	public void setMiRadio(double miRadio) {
		MiRadio = miRadio;
	}

	/**
	 * @return El nombre del tipo de instancia
	 */
	public String getClase() {
		return Clase;
	}

	public boolean isVivo() {
		return super.vivo;
	}

	/**
	 * TODO CON EL TEMA DE ESTAR VIVO SE TIENE QUE SOLUCIONAR EN CASO DE IRSE
	 * POR ABAJO
	 */
	public void setVivo(boolean vivo) {
		this.vivo = vivo;
		super.vivo = vivo;
	}

	/**
	 * se mueve mientras se mueva la nave
	 */
	public void moverEnXIzquierda(Chocable limitIzq) {
		this
				.setMiPosicion(this.MiPosicion
						.sumarPosicionX(-Controlador.velNave));
	}

	/**
	 * se mueve mientras se mueva la nave
	 */
	public void moverEnXDerecha(Chocable limitDer) {
		this.setMiPosicion(this.MiPosicion.sumarPosicionX(Controlador.velNave));
	}
}